<template>
  <div class="tabs-view">
    <a-tabs
      v-model="activeKey"
      :hide-add="true"
      type="editable-card"
      class="tabs"
      @change="changePage"
      @edit="editTabItem"
    >
      <template v-for="(pageItem, index) in tabsList">
        <a-tab-pane :key="pageItem.fullPath">
          <template slot="tab">
            <a-dropdown :trigger="['contextmenu']">
              <div style="display: inline-block">
                {{ pageItem.meta.title }}
              </div>
              <template slot="overlay">
                <a-menu style="user-select: none">
                  <a-menu-item
                    key="1"
                    :disabled="activeKey !== pageItem.fullPath"
                    @click="reloadPage(pageItem.fullPath)"
                  >
                    <a-icon type="reload" />
                    刷新
                  </a-menu-item>
                  <a-menu-item key="2" @click="removeTab(pageItem)">
                    <a-icon type="close" />
                    关闭
                  </a-menu-item>
                  <a-menu-divider />
                  <a-menu-item key="3" @click="closeLeft(pageItem, index)">
                    <a-icon type="vertical-right" />
                    关闭左侧
                  </a-menu-item>
                  <a-menu-item key="4" @click="closeRight(pageItem, index)">
                    <a-icon type="vertical-left" />
                    关闭右侧
                  </a-menu-item>
                  <a-menu-divider />
                  <a-menu-item key="5" @click="closeOther(pageItem)">
                    <a-icon type="column-width" />
                    关闭其他
                  </a-menu-item>
                  <a-menu-item key="6" @click="closeAll">
                    <a-icon type="minus" />
                    关闭全部
                  </a-menu-item>
                </a-menu>
              </template>
            </a-dropdown>
          </template>
        </a-tab-pane>
      </template>

      <div slot="tabBarExtraContent">
        <!-- <a-tooltip placement="top">
          <template slot="title">
            <span>刷新</span>
          </template>
          <a-icon type="reload" class="reload_btn" @click="reloadPage($route.fullPath)" />
        </a-tooltip> -->
        <a-dropdown :trigger="['hover']">
          <a class="ant-dropdown-link" @click.prevent>
            <a-icon type="down" :style="{ fontSize: '18px' }" />
          </a>
          <template slot="overlay">
            <a-menu style="user-select: none">
              <a-menu-item key="1" :disabled="activeKey !== $route.fullPath" @click="reloadPage($route.fullPath)">
                <a-icon type="reload" />
                刷新
              </a-menu-item>
              <a-menu-item key="2" @click="removeTab($route)">
                <a-icon type="close" />
                关闭
              </a-menu-item>
              <a-menu-divider />
              <a-menu-item key="5" @click="closeOther($route)">
                <a-icon type="column-width" />
                关闭其他
              </a-menu-item>
              <a-menu-item key="6" @click="closeAll">
                <a-icon type="minus" />
                关闭全部
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </div>
    </a-tabs>
    <div class="tabs-view-content">
      <!-- <keep-alive> -->
      <router-view></router-view>
      <!-- </keep-alive> -->
    </div>
  </div>
</template>

<script>
import storage from 'store'
import { mapGetters } from 'vuex'
import { TABS_ROUTES } from '@/store/mutation-types'
import { checkHasRoutePermission, allowList } from '@/router/router-guards'
import { TabsViewMutationType } from '@/store/modules/tabsView'
import components from '@/layouts/components/tabs/components'

export default {
  name: 'TabsView',
  components: {
    ...components
  },
  data() {
    return {
      activeKey: undefined
    }
  },
  computed: {
    ...mapGetters(['tabsList', 'menus'])
  },
  watch: {
    '$route.fullPath': {
      handler(to) {
        const whiteList = allowList
        // 不存在的路由
        const notFondRoutes = []
        this.tabsList.forEach(item => {
          if (!checkHasRoutePermission(item.name, this.$router)) {
            notFondRoutes.push(item.name)
          }
        })
        // 过滤不存在的路由
        if (notFondRoutes.length) {
          this.$store.commit(
            `tabsView/${TabsViewMutationType.InitTabs}`,
            this.tabsList.filter(item => !notFondRoutes.includes(item.name))
          )
        }
        if (whiteList.includes(this.$route.name)) return
        this.activeKey = to
        this.$store.commit(`tabsView/${TabsViewMutationType.AddTabs}`, this.getSimpleRoute(this.$route))
      },
      immediate: true
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      this.activeKey = this.$route.fullPath
      let routes = []
      try {
        const routesStr = storage.get(TABS_ROUTES)
        routes = routesStr ? JSON.parse(routesStr) : [this.getSimpleRoute(this.$route)]
      } catch (e) {
        routes = [this.getSimpleRoute(this.$route)]
      }
      // 初始化标签页
      this.$store.commit(`tabsView/${TabsViewMutationType.InitTabs}`, routes)
      // 在页面关闭或刷新之前，保存数据
      window.addEventListener('beforeunload', () => {
        storage.set(TABS_ROUTES, JSON.stringify(this.tabsList))
      })
    },
    // 获取简易的路由对象
    getSimpleRoute(route) {
      const { fullPath, hash, meta, name, params, path, query } = route
      return { fullPath, hash, meta, name, params, path, query }
    },
    // 刷新页面
    reloadPage(_fullPath) {
      if (this.activeKey !== _fullPath) return
      this.delKeepAliveCompName()
      this.$router.push({
        path: '/redirect' + this.$route.fullPath
      })
    },
    // 移除缓存组件名称
    delKeepAliveCompName() {
      if (this.$route.meta.keepAlive) {
        const name = this.$router.currentRoute.matched.find(item => item.name == this.$route.name)?.components?.default
          .name
        if (name) {
          this.$store.state.permission.keepAliveComponents = this.$store.state.permission.keepAliveComponents.filter(
            item => item != name
          )
        }
      }
    },
    // tabs 编辑（remove || add）
    editTabItem(targetKey, action) {
      if (action == 'remove') {
        this.removeTab(this.tabsList.find(item => item.fullPath == targetKey))
      }
    },
    // 关闭当前页面
    removeTab(route) {
      if (this.tabsList.length === 1) {
        return this.$message.warning('这已经是最后一页，不能再关闭了！')
      }
      this.delKeepAliveCompName()
      this.$store.commit(`tabsView/${TabsViewMutationType.CloseCurrentTabs}`, route)
      // 如果关闭的是当前页
      if (this.activeKey === route.fullPath) {
        const currentRoute = this.tabsList[Math.max(0, this.tabsList.length - 1)]
        this.activeKey = currentRoute.fullPath
        this.$router.push(currentRoute)
      }
    },
    // 切换页面
    changePage(key) {
      this.activeKey = key
      this.$router.push(key)
    },
    // 关闭左侧
    closeLeft(route, index) {
      this.$store.commit(`tabsView/${TabsViewMutationType.CloseLeftTabs}`, route)
      this.activeKey = route.fullPath
      this.$router.push({ path: route.fullPath, replace: true })
    },
    // 关闭全部
    closeAll() {
      localStorage.removeItem('routes')
      this.$store.commit(`tabsView/${TabsViewMutationType.CloseAllTabs}`)
      this.$router.push({ path: '/', replace: true })
    },
    // 关闭其他
    closeOther(route) {
      this.$store.commit(`tabsView/${TabsViewMutationType.CloseOtherTabs}`, route)
      this.activeKey = route.fullPath
      this.$router.push({ path: route.fullPath, replace: true })
    },
    // 关闭右侧
    closeRight(route, index) {
      this.$store.commit(`tabsView/${TabsViewMutationType.CloseRightTabs}`, route)
      this.activeKey = route.fullPath
      this.$router.push({ path: route.fullPath, replace: true })
    }
  }
}
</script>

<style lang="less" scoped>
.tabs-view {
  border-top: 1px solid #eee;

  ::v-deep .tabs {
    .ant-tabs-bar {
      padding: 4px 20px 0 10px;
      margin: 0;
      background-color: white;
      user-select: none;
    }

    .ant-tabs-tabpane {
      display: none;
    }

    .ant-tabs-tab:not(.ant-tabs-tab-active) {
      .anticon-close {
        width: 0;
        transition: width 0.3s;
      }

      &:hover .anticon-close {
        width: 16px;
      }
    }
  }

  .reload_btn {
    color: #1890ff;
    margin-right: 14px;
    font-size: 14px;
    transform: translateY(-2px);
    cursor: pointer;
  }

  .tabs-view-content {
    padding: 20px 14px 0;
    height: calc(100vh - 180px);
    overflow: auto;
  }
}
</style>
